﻿using dotnet_ef_admin.Src.Common.Const;
using dotnet_ef_admin.Src.Models;
using Microsoft.EntityFrameworkCore;

namespace dotnet_ef_admin.Src.Services;

public class UserService(DbCtx context) : IUserService {
    private readonly DbCtx _context = context;

    /// <summary>
    ///     获取所有用户的列表。
    /// </summary>
    /// <returns>返回一个包含所有用户的列表。</returns>
    public async Task<IEnumerable<User>> GetAllUsersAsync() {
        return await _context.Users.Include(u => u.Roles).ToListAsync();
    }

    /// <summary>
    ///     异步创建用户
    /// </summary>
    /// <param name="user">包含用户信息的创建请求对象</param>
    /// <returns>返回新创建的用户对象</returns>
    public async Task<User> CreateUserAsync(CreateUserRequest user) {
        // 初始化新的用户对象
        var newUser = new User {
            DeptId = user.DeptId,
            Email = user.Email,
            Gender = user.Gender ?? 0,
            Mobile = user.Mobile,
            Nickname = user.Nickname,
            Password = user.Password,
            Status = user.Status ?? StatusConstants.Disable,
            Username = user.Username
        };

        // 如果角色ID数组不为空，则为用户分配角色
        if (user.RoleIds.Length > 0)
            newUser.Roles = user.RoleIds.Select(roleId => new UsersOnRoles { RoleId = roleId, UserId = newUser.Id })
                .ToList();

        // 将新用户添加到数据库
        await _context.Users.AddAsync(newUser);
        // 提交更改到数据库
        await _context.SaveChangesAsync();

        // 返回新创建的用户对象
        return newUser;
    }

    /// <summary>
    ///     更新数据库中的现有用户。
    /// </summary>
    /// <param name="id">要更新的用户的ID。</param>
    /// <param name="user">包含更新信息的用户对象。</param>
    /// <returns>更新后的用户。</returns>
    public async Task UpdateUserAsync(int id, UpdateUserRequest user) {
        // 开启数据库事务
        await using var transaction = await _context.Database.BeginTransactionAsync();
        try {
            // 删除现有用户与角色关系
            await _context.UsersOnRoles.Where(ur => ur.UserId == id).ExecuteDeleteAsync();

            // 更新用户信息
            var existingUser = await _context.Users.FindAsync(id);
            if (existingUser == null) throw new Exception("用户不存在");

            _context.Entry(existingUser).CurrentValues.SetValues(user);
            await _context.SaveChangesAsync();

            // 插入新的用户与角色关系
            var roles = user.RoleIds.Select(roleId => new UsersOnRoles { RoleId = roleId, UserId = id }).ToList();
            if (roles.Count > 0) await _context.BulkInsertAsync(roles);

            // 提交事务
            await transaction.CommitAsync();
        } catch (Exception) {
            // 回滚事务
            await transaction.RollbackAsync();
            throw;
        }
    }

    /// <summary>
    ///     异步更新用户密码。
    /// </summary>
    /// <param name="id">要更新密码的用户ID。</param>
    /// <param name="request">包含新密码的请求对象。</param>
    public async Task UpdatePasswordAsync(int id, UpdatePasswordRequest request) {
        // 试图从数据库中查找指定ID的用户
        var user = await _context.Users.FindAsync(id);
        // 如果用户存在，则更新用户的密码
        if (user != null) {
            user.Password = request.Password;
            // 将更改保存到数据库
            await _context.SaveChangesAsync();
        }
    }

    /// <summary>
    ///     异步删除多个用户。
    /// </summary>
    /// <param name="ids">要删除的用户ID数组。</param>
    /// <returns>返回删除操作影响的行数。</returns>
    public async Task<int> DeleteManyAsync(int[] ids) {
        // 查询要删除的用户集合
        var deleteArr = await _context.Users.Where(r => ids.Contains(r.Id)).ToListAsync();
        // 从数据库中删除查询到的用户
        _context.Users.RemoveRange(deleteArr);
        // 返回删除操作影响的行数
        return await _context.SaveChangesAsync();
    }

    /// <summary>
    ///     异步查找用户表单
    /// </summary>
    /// <param name="id">用户ID</param>
    /// <returns>返回查找结果，包括用户的各种信息</returns>
    public async Task<FindFormResult> FindFormAsync(int id) {
        // 从数据库中查询指定ID的用户信息
        var result = await _context.Users
            .Where(u => u.Id == id) // 过滤条件：用户ID匹配
            .Select(u => new FindFormResult {
                // 选择需要的用户信息字段
                Id = u.Id,
                Username = u.Username ?? string.Empty, // 如果用户名为空，则用空字符串代替
                Nickname = u.Nickname ?? string.Empty, // 如果昵称为空，则用空字符串代替
                DeptId = u.DeptId ?? 0, // 如果部门ID为空，则用0代替
                Gender = u.Gender, // 直接获取性别信息
                Mobile = u.Mobile ?? string.Empty, // 如果手机号为空，则用空字符串代替
                Email = u.Email ?? string.Empty, // 如果邮箱为空，则用空字符串代替
                Status = u.Status, // 直接获取用户状态
                RoleIds = u.Roles.Select(ur => ur.RoleId).ToArray() // 将用户角色转换为角色ID数组
            })
            .FirstOrDefaultAsync(); // 获取第一个符合条件的用户，如果没有则返回默认值

        // 如果结果为空，则抛出异常提示用户不存在
        return result ?? throw new Exception("用户不存在");
    }


    /// <summary>
    ///     从数据库中删除用户。
    /// </summary>
    /// <param name="id">要删除的用户的ID。</param>
    public async Task DeleteUserAsync(int id) {
        var user = await _context.Users.FindAsync(id);
        if (user != null) {
            _context.Users.Remove(user);
            await _context.SaveChangesAsync();
        }
    }
}